package com.luoqiwen.android.sinaurldecoder

import com.squareup.okhttp.HttpUrl
import com.squareup.okhttp.OkHttpClient
import com.squareup.okhttp.Request
import org.junit.Assert.assertEquals
import org.junit.Test
import java.util.concurrent.TimeUnit

/**
 * Example local unit test, which will execute on the development machine (host).
 *
 * See [testing documentation](http://d.android.com/tools/testing).
 */
class ExampleUnitTest {
    @Test
    fun addition_isCorrect() {
        assertEquals(4, 2 + 2)
        val u = "https://weibo.cn/sinaurl?c=android&i=b7cd3c5&u=http%3A%2F%2Ft.cn%2FA6yGvXJH&ep=4575573395374596%2C6399718671&to=m&ua=HUAWEI-TEL-AN00a__weibo__12.1.2__android__android10&wm=9006_2001&v_p=89&from=10C1295060&gsid=_2A25PBuoVDeRxGeFK4lUZ9yfIzz-IHXVtknrdrDV6PUJbltANLVrakWpNQqOuvk1E8iDbjZzivZ3egvSTL3eJr4Oj&imei=&lfid=232532_mblog&skin=default&device_id=0f607264fc6318a92b9e13c65db7cd3c96d6e352&luicode=10000002&android_id=68d066266fe13b0d&network=WIFI"
        val map = decode(u, true, 3)

        debug(map.toString())
    }


    fun decode(input: String, secondaryDecode: Boolean, secondaryDecodeDepth : Int = 0) : MutableMap<String, MutableSet<HttpUrl>> {
        debug("URLDecoder: Decode task started: input=$input")

        val result = mutableMapOf<String, MutableSet<HttpUrl>>()
        val inputURL = HttpUrl.parse(input) ?: return result

        inputURL.queryParameterNames().forEach { name->
            debug("Input url parsed. Analyzing param values under key=$name:")
            inputURL.queryParameterValues(name).forEach { value->
                debug(" - Now analyzing value=$value")
                var parse = HttpUrl.parse(value)
                if (parse != null) {
                    debug("   Value parsed as httpurl.")
                    if (secondaryDecode) {
                        debug("   Working on secondary decode task. Depth: $secondaryDecodeDepth")
                        for ( i in 0 until secondaryDecodeDepth)
                            parse = secondaryDecode(parse)
                    }
                    debug("   Value=$value eventually parsed as httpurl=$parse")
                    if (!result.containsKey(name))
                        result[name] = mutableSetOf()
                    result[name]?.add(parse)
                }
            }
        }

        return result
    }

    private val Client = OkHttpClient()
    init {
        Client.setReadTimeout(3, TimeUnit.SECONDS)
        Client.setConnectTimeout(2, TimeUnit.SECONDS)
        Client.followRedirects = false
        Client.followSslRedirects = false
    }

    private fun secondaryDecode(input: HttpUrl): HttpUrl {
        debug("   Using okhttp for secondary decode.")
        debug("   Requesting server host: ${input.host()}, input_url=$input")
        val req = Request.Builder().get().url(input).build()
        val rep =    Client.newCall(req).execute()
        debug("   Response from ${input.host()} received. Now parsing header for key 'Location'")
        return HttpUrl.parse(rep?.header("Location", "")) ?: input
    }

    fun debug(txt: String) {
        println(txt)
    }
}